home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
CUGUK
/
COMMS
/
C035.ZIP
/
JMODEM_D.C
< prev
next >
Wrap
Text File
|
1990-02-17
|
9KB
|
163 lines
/****************************************************************************/
/* FILE JMODEM_D.C */
/* Created 11-JAN-1990 Richard B. Johnson */
/* 405 Broughton Drive */
/* Beverly, Massachusetts 01915 */
/* BBS (508) 922-3166 */
/* */
/* disp(); (Displays a "USAGE" message) */
/* encode(); (Data compression routine ) */
/* decode(); (Data expansion routine ) */
/* calc_crc(); (CRC checking and setting ) */
/* */
/****************************************************************************/
#include <stdio.h> /* For _printf() */
#include <stdlib.h> /* For _rotl() */
#include "jmodem.h" /* JMODEM primatives */
#pragma intrinsic (_rotl)
/****************************************************************************/
/* Print the 'Usage' prompt. */
/****************************************************************************/
void disp()
{
unsigned short i;
printf("\nUsage:");
for (i=1; i < 5; i++)
printf("\nJMODEM S%d FILENAME.TYP < Send a file using COM%d >",i,i);
for (i=1; i < 5; i++)
printf("\nJMODEM R%d FILENAME.TYP <Receive a file using COM%d>",i,i);
return;
}
/****************************************************************************/
/* Encode (compress) the input string. */
/* The routine looks for groups of identical characters and replaces them */
/* with the character 0xBB, a word denoting the number of characters to */
/* duplicate, followed by the character to duplicate. */
/* */
/****************************************************************************/
unsigned short encode(len, in_buffer, out_buffer)
unsigned short len; /* Length of input string */
unsigned char *in_buffer; /* Pointer to input buffer */
unsigned char *out_buffer; /* Pointer to outpup buffer */
{
register unsigned short i=0;
register unsigned short j=0;
unsigned char c; /* Character to replace */
unsigned char *in_limit; /* End of the input string */
unsigned char *out_limit; /* End of the output buffer */
in_limit = in_buffer + len; /* Calc buffer end only once */
out_limit = out_buffer + DAT_LEN; /* Calculate output buffer once */
while (in_buffer < in_limit) /* While more bytes in the buffer */
{
if (out_buffer > out_limit) /* If we exceeded the buffer size */
return JM_MAX; /* Show no compression possible */
if (*in_buffer == 0xBB || *in_buffer == *(in_buffer+1) )
{
*out_buffer++ = 0xBB; /* Insert token, bump pointer */
c = *in_buffer; /* Save duplicate character */
i = 0; /* Start duplicate char count */
while (*in_buffer++ == c) /* Count occurances of duplicates */
i++; /* Count identical characters */
in_buffer--; /* Backup to dissimilar character */
*out_buffer++ =
(unsigned char) i; /* Character count, low byte */
*out_buffer++ =
(unsigned char) (i >> 8); /* Character count, high byte */
*out_buffer++ = c; /* The duplicate character */
j += 4; /* Adjust char count */
}
else /* Else, just copy */
{
*out_buffer++ = *in_buffer++;
j++; /* Character count */
}
}
return j; /* New length */
}
/****************************************************************************/
/* Decode (expand) the encoded string. */
/* Routine checks for a sentinel byte, 0xBB, and if found, takes the */
/* following word as the number of identical bytes to add. The actual */
/* byte to add is located following the length-word. */
/* */
/****************************************************************************/
unsigned short decode(len, in_buffer, out_buffer)
unsigned short len; /* Length to input string */
unsigned char *in_buffer; /* Pointer to input buffer */
unsigned char *out_buffer; /* Pointer to output buffer */
{
register unsigned short i=0;
register unsigned short j=0;
unsigned char c;
unsigned char *limit; /* Length of input buffer */
limit = in_buffer + len; /* Set end pointer once */
while (in_buffer < limit)
{
if (*in_buffer == 0xBB ) /* If the sentinel byte */
{
in_buffer ++; /* Next character */
i = (unsigned short) *in_buffer++; /* Get low byte, incr */
i = i | (unsigned short)
(*in_buffer++) << 8; /* Get high byte, incr */
c = *in_buffer++; /* Get byte, incr */
for ( ; i >0; i--) /* Don't alter i at start */
{
*out_buffer++ = c; /* Expand byte */
j++; /* Character count */
}
}
else /* Else, just copy */
{
*out_buffer++ = *in_buffer++;
j++; /* Character count */
}
}
return j; /* New string length */
}
/****************************************************************************/
/* Calculate the simple JMODEM CRC */
/* Routine obtains a pointer to the buffer of characters to be checked. */
/* The first passed parameter is the length of the buffer. The CRC is */
/* returned. */
/* */
/****************************************************************************/
unsigned short calc_crc(command, length, buffer)
unsigned short command; /* Set or Check CRC */
unsigned short length; /* Buffer length */
unsigned char *buffer; /* Pointer to the buffer */
{
register unsigned short crc=0; /* Start at zero */
register unsigned short i; /* Byte count */
length -=2; /* Don't CRC the CRC */
do
{
crc += (unsigned short) *buffer++; /* Sum first */
i = length & 0x07; /* 7 bits max to rotate */
crc = _rotl(crc,i); /* Rotate i bits left */
} while (--length);
switch (command)
{
case GET_CRC:
{
i = (unsigned short) *buffer++;
i = i | (unsigned short) (*buffer << 8 );
return (crc - i); /* Return AX = 0 if CRC okay */
}
case SET_CRC:
{
*buffer++ = (unsigned char) crc;
*buffer = (unsigned char) (crc >> 8);
return crc; /* Return CRC though ignored */
}
default:
return JM_MAX; /* Bad data, buffer overflow */
}
}
/****************************************************************************/
/************************ E N D O F M O D U L E **************************/